<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="YeEBS" id="YeEBS"><span data-lake-id="ubde4a1f9" id="ubde4a1f9">典型回答</span></h1>
  <p data-lake-id="u9a8bcd8a" id="u9a8bcd8a"><br></p>
  <p data-lake-id="u6e3ff119" id="u6e3ff119"><span data-lake-id="udddf59ba" id="udddf59ba">在Mybatis的mapper文件中，可以使用#{param}和${param}来作为动态参数的替换。</span></p>
  <p data-lake-id="u13100fc7" id="u13100fc7"><span data-lake-id="u5fc95392" id="u5fc95392">​</span><br></p>
  <p data-lake-id="u209e363d" id="u209e363d"><span data-lake-id="ud2017661" id="ud2017661">使用${}方式传入的参数，mybatis不会对它进行特殊处理，而</span><strong><span data-lake-id="u484ac087" id="u484ac087">使用#{}传进来的参数，mybatis默认会将其当成字符串。</span></strong></p>
  <p data-lake-id="u73311a46" id="u73311a46"><br></p>
  <p data-lake-id="u8b9403ec" id="u8b9403ec"><span data-lake-id="u9599e759" id="u9599e759">#{}和${}在预编译处理中是不一样的。</span><strong><span data-lake-id="ubfc473be" id="ubfc473be">#{}类似jdbc中的PreparedStatement，对于传入的参数，在预处理阶段会使用?代替，可以有效的避免SQL注入</span></strong><span data-lake-id="u5dba852a" id="u5dba852a">。</span></p>
  <p data-lake-id="u3507c984" id="u3507c984"><span data-lake-id="u28a53d82" id="u28a53d82">​</span><br></p>
  <p data-lake-id="u7d122850" id="u7d122850"><span data-lake-id="u254afa1f" id="u254afa1f" class="lake-fontsize-12" style="color: rgb(51, 51, 51)">所以我们在</span><span data-lake-id="ua2afcf05" id="ua2afcf05">Mybatis</span><span data-lake-id="u8249ec67" id="u8249ec67" class="lake-fontsize-12" style="color: rgb(51, 51, 51)">中，能使用#{}的地方应尽量使用#{}，</span><strong><span data-lake-id="u9199af0b" id="u9199af0b" class="lake-fontsize-12" style="color: rgb(51, 51, 51)">但是有一些情况是必须要用</span></strong><strong><span data-lake-id="ubee817ff" id="ubee817ff">${}的，比如我们要把他用在order by、group by 等语句后面的时候</span></strong><span data-lake-id="ue41a79fc" id="ue41a79fc">。</span></p>
  <p data-lake-id="u1e6b5db0" id="u1e6b5db0"><span data-lake-id="u2a351cfb" id="u2a351cfb">​</span><br></p>
  <pre lang="java"><code>
order by ${sortParam} ${sortType} 


order by id desc;
</code></pre>
  <p data-lake-id="u308a9793" id="u308a9793"><br></p>
  <p data-lake-id="uf44cce08" id="uf44cce08"><span data-lake-id="u5a30181d" id="u5a30181d">当我们通过以上方式进行动态的选择排序字段的时候，就需要使用${}；</span></p>
  <p data-lake-id="ucc517325" id="ucc517325"><span data-lake-id="udee5c540" id="udee5c540">​</span><br></p>
  <h1 data-lake-id="eiPJh" id="eiPJh"><span data-lake-id="u7fb30100" id="u7fb30100">扩展知识</span></h1>
  <p data-lake-id="u7f9d6d5a" id="u7f9d6d5a"><br></p>
  <h2 data-lake-id="nE4Em" id="nE4Em"><span data-lake-id="u0bc98987" id="u0bc98987">${}的SQL注入问题</span></h2>
  <p data-lake-id="u48ffe157" id="u48ffe157"><br></p>
  <p data-lake-id="u47261825" id="u47261825"><span data-lake-id="ub456488f" id="ub456488f">MyBatis 中的 $ 符号在 SQL 查询中是会出现潜在的 SQL 注入问题的，因为 $ 符号会直接将参数的值替换到 SQL 查询中，而不会进行参数值的安全转义或预处理。这意味着如果不小心构造了恶意的参数值，就可能导致 SQL 注入攻击。</span></p>
  <p data-lake-id="ucc05fac0" id="ucc05fac0"><span data-lake-id="ue4661ec0" id="ue4661ec0">​</span><br></p>
  <p data-lake-id="ue3246c01" id="ue3246c01"><br></p>
  <p data-lake-id="u888ff79e" id="u888ff79e"><span data-lake-id="u26e36490" id="u26e36490">如果一定要使用${}的话，有以下几种方式可以避免被SQL注入：</span></p>
  <p data-lake-id="u4cc9c65d" id="u4cc9c65d"><span data-lake-id="u15f99a8e" id="u15f99a8e">​</span><br></p>
  <p data-lake-id="uf0fe7214" id="uf0fe7214"><strong><span data-lake-id="uda9577ed" id="uda9577ed">参数验证</span></strong><span data-lake-id="uae96fbd8" id="uae96fbd8" class="lake-fontsize-12" style="color: rgb(15, 15, 15)">：</span><span data-lake-id="u42a53e01" id="u42a53e01">在将变量传递到 SQL 语句之前，对输入的参数进行严格的验证。确保输入符合预期的格式，并且移除或转义可能的 SQL 控制字符。例如，如果你知道一个参数应该是一个整数，你可以先将其转换为整数。</span></p>
  <p data-lake-id="uef3c8815" id="uef3c8815"><span data-lake-id="ude68ca8d" id="ude68ca8d">​</span><br></p>
  <p data-lake-id="u63bd80ba" id="u63bd80ba"><strong><span data-lake-id="ud0e6daeb" id="ud0e6daeb">使用枚举或固定列表</span></strong><span data-lake-id="uf9463a19" id="uf9463a19">：如果可能的参数值是已知且数量有限的，比如排序字段（ASC, DESC），可以使用枚举或预定义的字符串列表来限制输入。比如说字段名，那么也可以定义一个枚举或者常量类，然后用户输入时做判断，是否规定的枚举项或者常量。</span></p>
  <p data-lake-id="u3da2f4e9" id="u3da2f4e9"><span data-lake-id="udb216df5" id="udb216df5">​</span><br></p>
  <p data-lake-id="u181b0318" id="u181b0318"><span data-lake-id="u21e63d94" id="u21e63d94">如：</span></p>
  <pre lang="java"><code>
public enum SortOrder {
    ASC, DESC
}

public void someMethod(SortOrder order) {
    // 在 MyBatis 映射中使用 ${order}
    // 检查是否是枚举项
    SortOrder.valueOf(order);
}
</code></pre>
 </body>
</html>